home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
language
/
embedded
/
simulato
/
v2_3_mc6.tz
/
v2_3_mc6
/
testfiles
/
main.asm
< prev
next >
Wrap
Assembly Source File
|
1994-05-02
|
16KB
|
351 lines
******************************************************************************
* ASSIGNMENT: #4--Programmer's utility
* MODULE: MAIN.
* DUE DATE: 12/4/92
* DESCRIPTION: This program is a utility designed to convert 16 bit
* hex or binary integers to their corresponding form.
* The hex numbers are given a sign using -, and binary
* numbers are assumed to be 2's complement represented.
* The command string will ignore spaces in the input.
* It will detect invalid characters and numbers that are
* out of range of a 16-bit answer. Leading zero's will be
* dropped from the input string, and leading zero's will
* not be put in the output. (This is why the parse routine
* is so long).
*
*******************************************************************************
**** RESOURCES ****
* D7 -> holds code for command to be executed.
*******************
**** SUBROUTINES ****
* WriteString -- writes string to screen.
* ReadString -- reads user string.
* WriteChar -- writes a single char. to screen
* HEX2BIN -- converts entered hex into binary string.
* BIN2HEX -- converts entered binary into hex string.
*********************
SECTION M,code ;define section for main
XREF HEX2BIN,BIN2HEX ;declare external references.
MAIN JSR WriteEOL ;write blanks
JSR WriteEOL ;so it's easier to read.
LEA PROMPT,A0 ;load in the prompt.
JSR WriteString ;and print to screen.
LEA NUMBER,A0 ;load place to put entered number.
JSR ReadString ;get the number from the user.
LEA NUMBER,A0 ;load place where # was entered.
JSR PARSENUM ;parse the entered number.
MOVE.B NUM_CASE,D7 ;get the command from the parser
CMPI.B #'$',D7 ;look @ first case.
BNE.S BIN_CASE ;if not first look @ nxt.
HEX_CASE MOVE.W D3,-(A7) ;push neg flag onto stack.
LEA BIN_STR,A5 ;load place of binary string to reg.
MOVE.L A5,-(A7) ;push onto stack.
MOVE.L A2,-(A7) ;load last chr. of parsed string
JSR HEX2BIN ;change input to binary string.
MOVEA.L (A7)+,A2 ;clean up the stack.
MOVEA.L (A7)+,A5 ;to avoid problems.
MOVE.W (A7)+,D3 ;of stack overflow.
JSR WriteEOL ;make a blank.
JSR WriteEOL ;so easy to read.
LEA START_MSG,A0 ;load first part of output.
JSR WriteString ;print out to screen
LEA P_NUM,A0 ;load the parsed number.
JSR WriteString ;print to screen.
LEA HEX_EQ_BIN,A0 ;load to print equal sign and %
JSR WriteString ;print to screen.
LEA BIN_STR,A0 ;load output binary string
JSR WriteString ;print to screen.
BRA.W MAIN ;begin again.
BIN_CASE CMPI.B #'%',D7 ;see if number was a binary entry.
BNE.W INV_CASE ;else look at next possibility.
MOVE.W D3,-(A7) ;move return param on stack 4 balance.
LEA HEX_STR,A5 ;load place to store hex string.
MOVE.L A5,-(A7) ;and store on stack for pass.
LEA P_NUM+1,A2 ;load 1st chr. of string to be converted.
MOVE.L A2,-(A7) ;and store on stack for pass.
JSR BIN2HEX ;change input string to hex string.
MOVEA.L (A7)+,A2 ;clean up the stack
MOVEA.L (A7)+,A5 ;to avoid problems of overflow.
MOVE.W (A7)+,D3 ;load return param. of neg. flag.
JSR WriteEOL ;make blanks for
JSR WriteEOL ;easy reading.
LEA START_MSG,A0 ;load first part of output.
JSR WriteString ;print to screen.
LEA P_NUM,A0 ;load parsed number.
JSR WriteString ;print to screen.
LEA EQUALS,A0 ;load spacing and equals sign.
JSR WriteString ;print to screen.
TST.W D3 ;test the negaitve flag.
BEQ.S 1$ ;if 0 the # is pos so branch
MOVE.B #'-',D0 ;else is neg
JSR WriteChar ;so print negative char.
1$ MOVE.B #'$',D0 ;load in the hex symbol
JSR WriteChar ;print to screen.
LEA HEX_STR,A0 ;load the results
JSR WriteString ;and print to the screen.
BRA.W MAIN ;begin agian.
INV_CASE CMPI.B #'!',D7 ;compare to invalid char. case.
BNE.S BIG_CASE ;else look @ nxt. case.
JSR WriteEOL ;spacing.
JSR WriteEOL ;spacing.
LEA INV_MSG,A0 ;load error msg.
JSR WriteString ;and print to screen.
LEA NUMBER,A0 ;load in erroneous number.
JSR WriteString ;print to screen.
LEA HELP_MSG,A0 ;load in helpfull msg.
JSR WriteString ;and print to screen.
BRA.W MAIN ;and begin again.
BIG_CASE CMPI.B #'*',D7 ;compare to out of range case.
BNE.S END_CASE ;ele look @ nxt.
JSR WriteEOL ;spacing.
JSR WriteEOL ;spacing.
LEA BIG_MSG,A0 ;load error msg.
JSR WriteString ;and print to screen.
LEA NUMBER,A0 ;load errorneous number.
JSR WriteString ;print to screen.
LEA HELP_MSG,A0 ;load in nice msg.
JSR WriteString ;and print to screen.,
BRA.W MAIN ;try again
END_CASE CMPI.B #'.',D7 ;compare to end char.
BNE.S WHAT_CASE ;else invalid char.
BRA.S END_IT_ALL ;end program.
WHAT_CASE JSR WriteEOL ;spacing
JSR WriteEOL ;spacing
LEA NUMBER,A0 ;load erroroneous commmand
JSR WriteString ;and print to screen.
LEA WHAT_MSG,A0 ;load error msg.
JSR WriteString ;print
BRA.W MAIN ;try agian.
END_IT_ALL MOVE #228,D7 ;end routine.
TRAP #14 ;ends prog.
OH_NO BRA.S OH_NO ;you really screwd up if you're here.
**** SUBROUTINE PARSENUM ****
* The purpose of this subroutine is to take the user input string, which
* may contain upper or lower case letters, numbers, or other spurious
* characters and place them in a standard format. This routine also
* checks to see if conversion is possible.
*****************************
**** RESOURCES ****
* INPUTS: A0 -> input string.
* OUTPUT: A2 -> pointer to last character in string.
* D3 -> negative flag.
* P_NUM -> memory location, parsed string.
* NUM_CASE -> memory location, action to be taken by main.
* HF -> memory location, HEX OR BINARY INPUT FLAG.
* D0 -> digit counter.
* D1 -> character being operated on.
********************
PARSENUM CLR.L D3 ;clear the negative flag.
CLR.L D0 ;clear the counter.
CLR.L D4 ;clear found chr. other than leading 0
LEA P_NUM,A2 ;load in place of output str.
P_FIRST MOVE.B (A0)+,D1 ;move in first chr. in string.
CMPI.B #'A',D1 ;look for upper-case chr.
BLT.S P_NOTCHR ;if less than 'A' it is not a chr.
CMPI.B #'F',D1 ;look @ upper limit for upper cse.
BGT.S P_NOTUCHR ;if greater cannot be upper case.
BRA.S P_SETHEX ;else it is a chr. and the # is hex.
P_NOTUCHR CMPI.B #'a',D1 ;look @ lower case chr.
BLT.S P_NOTCHR ;if less than 'a' it is not a char.
CMPI.B #'f',D1 ;look @ upper limit for lower case.
BGT.S P_NOTCHR ;if greater it is not a lower chr.
SUBI.B #$20,D1 ;make chr. upper case.
BRA.S P_SETHEX ;else it is a lower chr. and the # is hex.
P_NOTCHR CMPI.B #'0',D1 ;compare to lower bounds for #
BLT.S P_NOTNUM ;if it is lower it is not a #
CMPI.B #'9',D1 ;compare to upper bounds for #
BGT.S P_NOTNUM ;if it is higher then it is not #
BRA.S P_SETHEX ;else it is a number and the # is hex.
P_NOTNUM CMPI.B #'%',D1 ;compare to binary string format chr.
BNE.S P_NOTBIN ;if it is not then # is not binary.
BRA.S P_SETBIN ;else # is bin and set up.
P_NOTBIN CMPI.B #'-',D1 ;compare to negative format chr.
BNE.S P_NOTNEG ;if it is not then look for end
BRA.S P_SETNEG ;else it is neg. so set it.
P_NOTNEG CMPI.B #0,D1 ;compare to end of string.
BNE.S P_NOTEND ;if it is not end look for space.
MOVE.B #'?',NUM_CASE ;else the command is unknown put in chr.
BRA.W END_PARSE ;and return.
P_NOTEND CMPI.B #' ',D1 ;compare to the space chr.
BEQ.W P_FIRST ;if equal keep looking.
CMPI.B #'.',D1 ;compare to exit chr.
BNE.S P_NOTEXIT ;if it is
MOVE.B #'.',NUM_CASE ;place control chr.
BRA.W END_PARSE ;and return.
P_NOTEXIT MOVE.B #'!',NUM_CASE ;else there is an invalid chr. so
BRA.W END_PARSE ;return.
P_SETNEG MOVE.B #'-',(A2) ;put the chr. into the parse string.
ADDQ.W #1,D3 ;set the negative flag.
P_SETHEX MOVE.W #1,HF ;set the hex flag.
TST.W D3 ;see if # was negative.
BEQ.S P_POS ;if zero # is positive.
ADDQ.L #1,A2 ;if negative pre-increment pointer.
P_POS MOVE.B #'$',(A2) ;else move in format for hex #
MOVE.B #'$',NUM_CASE ;and set control chr. for main.
TST.W D3 ;test neg. flag again
BNE.S P_FIND2END ;if # is neg. there is still no chr
CMPI.B #'0',D1 ;look for leading 0
BEQ.S P_FIND2END ;if is there is still no chr.
MOVE.W #1,D4 ;move non-leading zero flag.
ADDQ.L #1,A2 ;else there is so place in pre inc. ptr.
MOVE.B D1,(A2) ;and place chr. in parse string.
ADDQ.W #1,D0 ;increment digit counter.
BRA.S P_FIND2END ;continue the process.
P_SETBIN MOVE.B #'%',NUM_CASE ;put in binary control chr.
MOVE.B #'%',(A2) ;move format chr. in parse string.
P_FIND2END MOVE.B (A0)+,D1 ;load the next chr.
CMPI.B #'A',D1 ;compare to lower bounds for upper
BLT.S P_NUMBER ;if lower is not a chr.
CMPI.B #'F',D1 ;compare to upper bounds for upper.
BGT.S P_LOWERCSE ;if higher not an upper case.
BRA.S P_FOUNDCHR ;else it is upper so look at chr.
P_LOWERCSE CMPI.B #'a',D1 ;compare to lower bounds for lower
BLT.S P_NUMBER ;if not is not a chr.
CMPI.B #'f',D1 ;compare to upper bounds for lower
BGT.S P_SPACE ;if higher is invalid so do one other.
SUBI.B #$20,D1 ;else is lower so make upper.
BRA.S P_FOUNDCHR ;and look @ chr.
P_NUMBER CMPI.B #'0',D1 ;compare to lower bounds for #
BLT.S P_NULL ;If not look a null case.
CMPI.B #'9',D1 ;compare to upper bounds for #
BGT.S P_SPACE ;if not is invalid so do one last.
BRA.S P_FOUNDNUM ;else look @ num.
P_NULL CMPI.B #0,D1 ;compare to null chr.
BEQ.W END_PARSE ;end of string to parse.
P_SPACE CMPI.B #' ',D1 ;compare to space
BEQ.W P_FIND2END ;if space get nxt. chr.
MOVE.B #'!',NUM_CASE ;set invalid control chr.
BRA.W END_PARSE ;and end parse.
P_FOUNDCHR TST HF ;test the hex flag.
BNE.S P_ISDIGIT ;if flag is zero then this is invalid
MOVE.B #'!',NUM_CASE ;so set control chr.
BRA.W END_PARSE ;and leave.
P_ISDIGIT ADDQ.W #1,D0 ;increment digit counter.
CMPI.W #4,D0 ;check to see if there are too
BLE.S P_ISSHORT ;many digits.
MOVE.B #'*',NUM_CASE ;send control chr.
BRA.W END_PARSE ;and leave.
P_ISSHORT MOVE.W #1,D4 ;set found non-leading 0 flag.
ADDQ.L #1,A2 ;else is valid so
MOVE.B D1,(A2) ;pre-increment and place in parse string.
BRA.W P_FIND2END ;keep looking.
P_FOUNDNUM TST.W D4 ;test if leading 0 flag is set.
BNE.S P_NOT0 ;check if num is a leading 0
CMPI.B #'0',D1 ;compare to 0 char.
BNE.S P_NOT0 ;if not 0 add to string
BRA.W P_FIND2END ;else ignore.
P_NOT0 TST HF ;test the hex flag.
BEQ.S P_NUMISBIN ;if zero number is binary.
ADDQ.W #1,D0 ;else increment digit counter.
CMPI.W #4,D0 ;and check to see if there are too many.
BLE.S P_ISSMALL ;if there are
MOVE.B #'*',NUM_CASE ;send control chr.
BRA.S END_PARSE ;and leave.
P_ISSMALL MOVE.W #1,D4 ;set non-leading 0 flag.
ADDQ.L #1,A2 ;else pre-increment and
MOVE.B D1,(A2) ;place in parse string.
BRA.W P_FIND2END ;keep looking.
P_NUMISBIN TST.W D4 ;test if chr. other than leading is found
BNE.S P_NOTBIN0 ;if not 0 is not a leading 0.
CMPI.B #'0',D1 ;compare to the 0 char.
BNE.S P_NOTBIN0 ;if not 0 ok
BRA.W P_FIND2END ;else ignore
P_NOTBIN0 ADDQ.W #1,D0 ;increment the digit counter.
CMPI.B #'1',D1 ;compare to highest binary digit.
BLE.S P_BININRANGE ;if number is greater
MOVE.B #'!',NUM_CASE ;send control chr.
BRA.S END_PARSE ;and leave.
P_BININRANGE CMPI.W #16,D0 ;check the # of digits
BLE.S P_BINSMALL ;if less than limit ok
MOVE.B #'*',NUM_CASE ;else place control chr.
BRA.S END_PARSE ;and leave.
P_BINSMALL CMPI.W #9,D0 ;check for spacing
BNE.S P_PUT1 ;if is place
ADDQ.L #1,A2 ;a space into the
MOVE.B #' ',(A2) ;output string.
P_PUT1 ADDQ.L #1,A2 ;else pre-increment
MOVE.B D1,(A2) ;and place in parse string.
MOVE.W #1,D4 ;move in found other than leading 0 flg.
BRA.W P_FIND2END ;keep looking.
END_PARSE MOVE.B #0,1(A2) ;place term. in string.
MOVE.W #0,HF ;clear hex flag for next
RTS ;return.
; NOLIST
DC.W 0
Include "samples.asm"
; LIST
**** MESSAGE AND VARIABLE AREA ****
***********************************
CNOP 0,2
PROMPT DC.B '>> ',0
CNOP 0,2
START_MSG DC.B ' ',0
CNOP 0,2
HEX_EQ_BIN DC.B ' = %',0
CNOP 0,2
INV_MSG DC.B ' You have entered an invalid character in the number',13,10
DC.B ' ',0
CNOP 0,2
BIG_MSG DC.B ' The number you have entered is to big for its type',13,10
DC.B ' ',0
CNOP 0,2
WHAT_MSG DC.B ' -- What???',0
CNOP 0,2
HELP_MSG DC.B 13,10,' Please check your number and try again.',0
CNOP 0,2
EQUALS DC.B ' = ',0
CNOP 0,2
NUMBER DS.B 40
P_NUM DS.B 20
HF DC.W 0
BIN_STR DS.B 20
HEX_STR DS.B 8
NUM_CASE DC.W 0
END